﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace EarthImitate
{

    public abstract class Planet
    {
        #region Members

        protected int phanHoach;
        protected float gocQuay;
        protected double gocPhi;
        protected double gocTeta;
        protected int banKinh;
        protected Point2D gocToaDo;
        protected Color colorLine;

        protected Color ColorLine
        {
            get { return colorLine; }
            set { colorLine = value; }
        }
        protected B_Rep wireFrame = new B_Rep();
        #endregion

        #region Constructor
        protected Planet()
        {
        }
        public Planet(int rTraiDat, int phanHoach, float goc, double phiTraiDat, double tetaTraiDat, Point2D p0, Color colorLine)
        {
            this.banKinh = rTraiDat;
            this.phanHoach = phanHoach;
            this.gocQuay = goc;
            this.gocPhi = phiTraiDat;
            this.gocTeta = tetaTraiDat;
            this.colorLine = colorLine;
        }

        #endregion

        #region Properties
        public B_Rep WireFrame
        {
            get { return wireFrame; }
            set { wireFrame = value; }
        }


        public float GocQuay
        {
            get { return gocQuay; }
            set { gocQuay = value; }
        }

        public int PhanHoach
        {
            get { return phanHoach; }
            set { phanHoach = value; }
        }

        public double GocPhi
        {
            get { return gocPhi; }
            set { gocPhi = value; }
        }


        public double GocTeta
        {
            get { return gocTeta; }
            set { gocTeta = value; }
        }
        public int BanKinh
        {
            get { return banKinh; }
            set { banKinh = value; }
        }

        public Point2D GocToaDo
        {
            get { return gocToaDo; }
            set { gocToaDo = value; }
        }
        public double GocToaDoX
        {
            get { return gocToaDo.x; }
            set { gocToaDo.x = value; }
        }
        public double GocToaDoY
        {
            get { return gocToaDo.y; }
            set { gocToaDo.y = value; }
        }
        #endregion
        /// <summary>
        /// Khois the tao B rep.
        /// </summary>

        public void InitWireframe()
        {
            {
                wireFrame.nPoly = phanHoach * phanHoach + phanHoach;
                wireFrame.nVert = phanHoach * phanHoach + phanHoach; //PH * PH + PH;

                wireFrame.vert = new Point3D[wireFrame.nVert];
                wireFrame.poly = new PolygonType[wireFrame.nPoly];

                // Math.PI * 2 = 360
                double a = 0;
                double da = Math.PI / phanHoach;
                double c = 0;
                double dc = Math.PI * 2 / phanHoach;

                // phan hoach tren nua duong tron tren mat phang oxy
                for (int i = 0; i < phanHoach + 1; i++)
                {
                    // 1.
                    wireFrame.vert[i].z = 0;
                    wireFrame.vert[i].y = banKinh * Math.Cos(a);
                    wireFrame.vert[i].x = banKinh * Math.Sin(a);

                    a += da;

                }

                // phan hoach tren cac nua duong tron con lai, voi goc quay la c
                for (int i = 0; i < phanHoach - 1; i++)
                {
                    c += dc;

                    for (int j = 0; j < phanHoach + 1; j++)
                    {
                        wireFrame.vert[j + (i + 1) * phanHoach + (i + 1)].x = wireFrame.vert[j].x * Math.Cos(c) + wireFrame.vert[j].z * Math.Cos(c);
                        wireFrame.vert[j + (i + 1) * phanHoach + (i + 1)].y = wireFrame.vert[j].y;
                        wireFrame.vert[j + (i + 1) * phanHoach + (i + 1)].z = -wireFrame.vert[j].x * Math.Sin(c) + wireFrame.vert[j].z * Math.Cos(c);
                    }
                }

                int m = 0;
                for (int i = 0; i < phanHoach * phanHoach - 2; i++)
                {
                    if (m == phanHoach)
                    {
                        m = 0;
                    }

                    var mat = new PolygonType();
                    mat.Visible = 1;
                    mat.PColor = Color.GreenYellow;
                    mat.NVert = 4;
                    mat.Vertexes = new int[mat.NVert];

                    mat.Vertexes[0] = m + ((i / phanHoach) * phanHoach);
                    mat.Vertexes[1] = m + ((i / phanHoach) * phanHoach) + 1;
                    mat.Vertexes[2] = m + ((i / phanHoach) + 1) * phanHoach + 2;
                    mat.Vertexes[3] = m + ((i / phanHoach) + 1) * phanHoach + 1;

                    wireFrame.poly[i] = mat;

                    m++;
                }

                for (int i = 0; i < phanHoach; i++)
                {
                    var mat = new PolygonType();
                    mat.Visible = 1;
                    mat.PColor = Color.GreenYellow;
                    mat.NVert = 4;
                    mat.Vertexes = new int[mat.NVert];

                    mat.Vertexes[3] = i;
                    mat.Vertexes[2] = i + 1;
                    mat.Vertexes[1] = i + phanHoach * phanHoach - 2 + 2;
                    mat.Vertexes[0] = i + phanHoach * phanHoach - 2 + 1;

                    wireFrame.poly[(phanHoach * phanHoach - 2) + i] = mat;
                }
            }

        }


        public void veSS_viewxy(Graphics graphics)
        {
            Drawing.veSS_viewxyMT(graphics, this.wireFrame, this.gocPhi, this.gocTeta, this.gocToaDo, this.ColorLine);
        }
        public void bienB_repOX()
        {
            Drawing.bienB_repOX(ref this.wireFrame, gocQuay);
        }
        public void bienB_repOY(ref B_Rep w, float a)
        {
            Drawing.bienB_repOY(ref this.wireFrame, gocQuay);
        }
        public void bienB_repOZ(ref B_Rep w, float a)
        {
            Drawing.bienB_repOZ(ref this.wireFrame, gocQuay);
        }
        public void khuMatKhuat(Vector vTraiDat)
        {
            Drawing.khuMatKhuat(ref this.wireFrame, vTraiDat);
        }
        public void tinhPhapVector()
        {
            Drawing.tinhPhapVector(ref this.wireFrame, gocPhi, gocTeta);
        }
        public abstract void Draw(Graphics graphics);
    }
}
